home *** CD-ROM | disk | FTP | other *** search
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "cgilib.h"
-
- #define NEEDS_ENCODE(x) (!(islower(x)||isupper(x)||isdigit(x)||(x==' ')))
-
- void decodeData(char *queryString)
- {
- /* Temporary variables */
- int i = 0, j = 0, max = 0;
- char c;
-
- /*
- * Loop over the string.
- * We use two loop indices,
- * i is the actual current character
- * j is used to move ahead when hex codes are found
- * Two indices are needed since the string shrinks
- * as hex-codes are turned into single characters.
- * The loop ends when the '\0' character has been "copied".
- */
- if(queryString) max = strlen(queryString) + 1;
-
- for (i=0, j=0; j < max; ++i, ++j)
- {
- /* If we have found hex-codes, j>i so copy the data down. */
-
- queryString[i] = queryString[j];
-
- if ('+' == queryString[i]) /* Convert pluses to spaces */
- {
- queryString[i] = ' ';
- }
- else if ('%' == queryString[j])/* Convert hex codes */
- {
- /*
- * Get the first number of the hex code, and store it
- * as a char.
- */
-
- c = ((queryString[j+1] >= 'A') ?
- ((queryString[j+1] & 0xdf) - 'A') + 10
- : (queryString[j+1] - '0'));
- /*
- * The first hex-code was the 16 places, so multiply
- * c by 16.
- */
-
- c *= 16;
-
- /*
- * Get the second number in the hex code and add that
- * to the value of c.
- * c now stores the correct character for the hex code.
- */
- c += ((queryString[j+2] >= 'A') ?
- ((queryString[j+2] & 0xdf) - 'A') + 10
- : (queryString[j+2] - '0'));
-
- /* Replace the % char we copied with the actual character. */
- queryString[i] = c;
-
- /* Move j past the hex-code */
- j += 2;
- }
- }
- }
-
- /* encodeData() encodes a string for CGI */
- void encodeData(String aString)
- {
- int x,size,l,push = 0;
-
- if(aString->string != NULL)
- {
-
- /* figure out the size after encoding */
- l=string_length(aString);
-
- for(x=0;x<l;x++)
- {
- if(NEEDS_ENCODE(aString->string[x]))
- {
- push+=2;
- }
-
- }
-
- /* If we encountered characters to encode, encode them */
- if(push != 0)
- {
- /* Grow as needed */
- string_setSize(aString,l+push+1,0);
-
- /* Start encoded, back to front to reduce copying */
- for(x=l;x>=0;x--)
- {
-
- if((NEEDS_ENCODE(aString->string[x]))
- &&(aString->string[x] != '\0'))
- {
- int tmp;
-
- tmp = (aString->string[x])%16;
- aString->string[x+push] = (tmp>=10)? (tmp-10 + 'A') : (tmp+'0');
- push--;
-
- tmp = (aString->string[x])/16;
- aString->string[x+push] = (tmp>=10)? (tmp-10 + 'A') : (tmp+'0');
-
- push--;
- aString->string[x+push] = '%';
- }
- else/*push the other char back*/
- {
- aString->string[x+push] = aString->string[x];
- }
- }
- }
-
- /*Convert the spaces to pluses */
- for(x=0;aString->string[x] != '\0';x++)
- {
- if(aString->string[x] == ' ') aString->string[x] = '+';
- }
-
- }
- }
-
- /*
- * encodeDictionary() encodes a dictionary in the form
- * of CGI data.
- */
- String encodeDictionary(Dictionary dataDict)
- {
- String returnString = 0;
- DictState state;
- char *key;
- void *value;
- String buffer;
- int needAmp = 0;
-
- /* allocate the string */
- returnString = string_alloc(512);
- buffer = string_alloc(128);
-
- /* Create a dictionary state */
- state = dict_initState(dataDict);
-
- /* Calculate how long the string will be */
-
- while(dict_nextState(&state))
- {
- key = state.curNode->key;
-
- /* If this isn't a multiple value, encode and append it */
- if(key && strncmp(key,"A_",2))
- {
- value = state.curNode->value;
-
- string_setStringValue(buffer,key);
- encodeData(buffer);
-
- if(needAmp)
- {
- string_appendChar(returnString,'&');
- }
-
- string_appendString(returnString,buffer->string);
- string_appendChar(returnString,'=');
-
- if(value)
- {
- string_setStringValue(buffer,value);
- encodeData(buffer);
- }
- else
- {
- string_empty(buffer);
- }
-
- string_appendString(returnString,buffer->string);
-
- needAmp = 1;
- }
- }
-
- string_free(buffer);
- return returnString;
- }
-
- int parseData(char *queryString, Dictionary dataDict)
- {
- /* Temporary variables */
- char *cursor = (char *)0;
-
- char *key = (char *)0, *value = (char *)0;
-
- char *sbegin = (char *)0, *send = (char *)0;
-
- int charsToCopy = 0;
-
- /* For example take queryString = "key=value&key1=value1" */
-
- if(queryString != (char *)0)
- {
- cursor = queryString;
- }
- else
- {
- return 0;
- }
-
- do{/* Loop while we are finding keys */
-
- key = 0;/* Reset the tmp key */
-
- value = 0;/* Reset the tmp value */
-
- /*
- * Reset the search pointer, sbegin
- *
- * key=value&key1=value1
- * ^ ^
- * | |
- * pass 1 pass 2
- *
- */
-
- sbegin = cursor;
-
- /*
- * Move sbegin past any next special char, & or =
- *
- * key=value&key1=value1
- * ^ ^
- * | |
- * pass 1 pass 2
- *
- */
-
- sbegin += strspn(sbegin, "=&");
-
- /* Check if we are at the end of the query string */
-
- if(*sbegin == '\0') /* If at end, make the key and cursor = NULL */
- {
- cursor = (char *) 0;
- key = cursor;
- }
- else /* Otherwise, find the key */
- {
- /* Reset the number of characters in the key */
-
- charsToCopy = 0;
-
-
- /*
- * Find the end of the key
- *
- * key=value&key1=value1
- * ^ ^
- * | |
- * pass 1 pass 2
- *
- */
- send = sbegin + strcspn(sbegin,"=&");
-
- /* Check if the end of the key is the end of the string */
-
- if('\0' != (*send)) /* If not, calculate the length of key */
- {
- /*
- * Find send past the =
- *
- * key=value&key1=value1
- * ^ ^
- * | |
- * pass 1 pass 2
- *
- */
- send++;
- charsToCopy = strlen(sbegin) - strlen(send) - 1;
- }
- else /* Otherwise, key is whats left */
- {
- charsToCopy = strlen(sbegin);
- }
-
- /* Move the cursor to the end of the key */
-
- cursor = send;
-
- /* Allocate memory for the key */
-
- key = (char *) malloc(sizeof(char)*(charsToCopy +1));
-
- /* Copy the correst number of characters to the key string */
-
- strncpy(key,sbegin,charsToCopy);
-
- /* End the key string with a '\0' */
-
- key[charsToCopy] = '\0';
- }
-
- /* If we have a key, try to read the value */
-
- if( key && (*key != '\0')){
-
- /*
- * See if the next character is a &,
- * if it is the key has an empty value.
- */
-
- if(('\0' != *cursor)
- &&('&' != *cursor))
- {
- /*
- * Find the beginning of the value
- *
- * key=value&key1=value1
- * ^ ^
- * | |
- * pass 1 pass 2
- *
- */
-
- sbegin = cursor;
- sbegin += strspn(sbegin, "=&");
-
- /* Check if we found a vlaue */
-
- if(*sbegin == '\0') /* If not set the value and cursor to 0 */
- {
- cursor = (char *) 0;
- value = cursor;
- }
- else /* Otherwise, find the value */
- {
- /* Reset the length of the value string */
-
- charsToCopy = 0;
-
- /*
- * Find the end of the value
- *
- * key=value&key1=value1
- * ^ ^
- * | |
- * pass 1 pass 2
- *
- */
-
- send = sbegin + strcspn(sbegin,"=&");
-
- /* Check if the value is at the end of the string */
-
- if('\0' != (*send)) /* If not, calculate the length */
- {
- /*
- * Move send past the &
- *
- * key=value&key1=value1
- * ^ ^
- * | |
- * pass 1 pass 2
- *
- */
- send++;
- charsToCopy = strlen(sbegin)
- - strlen(send) - 1;
- }
- else /* Otherwise, the length is from the start to '\0'*/
- {
- charsToCopy = strlen(sbegin);
- }
-
- /*
- * Reset the cursor
- *
- * key=value&key1=value1
- * ^ ^
- * | |
- * pass 1 pass 2
- *
- */
-
- cursor = send;
-
- /* Allocate space for the value string */
-
- value = (char *)
- malloc(sizeof(char)*(charsToCopy +1));
-
- /* Copy the value string, and add a '\0' */
-
- strncpy(value,sbegin,charsToCopy);
- value[charsToCopy] = '\0';
- }
-
- /*
- * Decode the key and value then,
- * print them
- */
-
- decodeData(key);
- decodeData(value);
-
- }
- else/* Key has an empty value */
- {
- /*
- * Decode the key, then
- * print the key and an empty value
- */
-
- decodeData(key);
-
- value = malloc(sizeof(char) * 1);
- value[0] = '\0';
- }
-
- /*
- * Insert the value into the dictionary, but
- * allow for multiple values on key.
- * Put multiple values into an Array, with the key,
- * A_key.
- */
-
- /* Check if this is a multiple value */
- if(dict_isKey(dataDict,key))
- {
- /* Create the name for the array key */
- char *aName;
-
- aName = (char *) malloc((strlen(key)+3) * sizeof(char));
-
- sprintf(aName,"A_%s",key);
-
- /* Check if the array is in the dict, already */
-
- if(dict_isKey(dataDict,aName))
- {
- /* Add the new value to the array */
-
- Array theArray = 0;
-
- theArray = (Array) dict_valueForKey(dataDict,aName);
-
- array_addItem(theArray,value);
-
- /* Set the dictionaries value, to the latest */
-
- dict_setValueForKey(dataDict, key, value);
-
- }
- else /* If not, ... */
- {
- /* Create the array */
-
- Array theArray = 0;
-
- theArray = array_alloc(3);
-
- /* Add the first value to the array */
-
- array_addItem(theArray, dict_valueForKey(dataDict,key));
-
- /* Add the new value to the array */
-
- array_addItem(theArray,value);
-
- /* Set the dictionaries value, to the latest */
-
- dict_setValueForKey(dataDict, key, value);
-
- /* Add the array to the dictionary */
-
- dict_setValueForKey(dataDict, aName, (void *)theArray);
-
- }
-
-
- free(aName);
- }
- else /* If not, simple insert the value */
- {
- dict_setValueForKey(dataDict, key, value);
- }
-
- }
-
- }while(key && ('\0' != *key) && ('\0' != *cursor));
-
- return 1;/* Return 1 for success */
- }
-
- void readGetData(char **aString)
- {
- /* The data after it is read in */
- char *queryString;
- int len = 0;
-
- queryString = getenv("QUERY_STRING");
-
- if(queryString)
- {
- len = strlen(queryString);
-
- *aString = malloc(sizeof(char) * len);
-
- strcpy(*aString,queryString);
- }
- else
- {
- len = 1;
-
- *aString = malloc(sizeof(char) * len);
-
- **aString = '\0';
- }
- }
- void readPostData(char **aString)
- {
- /* The data after it is read in */
- char *queryString;
-
- /* The amount of data to read */
- int contentLength;
-
- /* Temporary variables for storing envvar and iterating */
- char *sizeString;
- int i;
-
- /* Read the environment variable CONTENT_LENGTH */
-
- sizeString = getenv("CONTENT_LENGTH");
-
-
- /* If the env. var. existed, convert the string to an integer */
-
- if (sizeString)
- {
- contentLength = atoi( sizeString );
- }
- else
- {
- contentLength = 0;
- }
-
- /*
- * If there is a non-zero amount of data,
- * alloc a string big enough to hold it.
- */
- if ( 0 != contentLength)
- {
- /* Notice that we add one to hold the null, '\0', character. */
- queryString = (char *) malloc(sizeof(char) * (contentLength + 1) );
- }
- else
- {
- queryString = (char *) 0;
- }
-
- /* If the malloc succeeded, read the data. */
-
- if ( queryString )
- {
- i = 0;
-
- /*
- * Use fgetc to read the data,
- * iterating until the exact number of characters is read.
- */
- while( i < contentLength)
- {
- queryString[ i++ ] = fgetc(stdin);
- }
-
- /* Add the null, '\0', character to the end. */
-
- queryString[ i ] = '\0';
-
- /* Set the arguement to point to the data. */
-
- *aString = queryString;
-
- }
- else
- {
- *aString = malloc(sizeof(char));
-
- **aString = '\0';
- }
- }
-
- void readData(char **aString)
- {
- char *requestType = (char *) 0;
-
-
- /* Read the request type */
-
- requestType = getenv("REQUEST_METHOD");
-
- /*
- * If it is a GET request use readGetData,
- * otherwise, if it is a POST request, use readPostData.
- */
-
- if(requestType && !strcmp(requestType,"GET"))
- {
- readGetData(aString);
- }
- else if(requestType && !strcmp(requestType,"POST"))
- {
- readPostData(aString);
- }
- else
- {
- *aString = malloc(sizeof(char));
-
- **aString = '\0';
- }
- }
-
- Dictionary readParse()
- {
- Dictionary returnData;
- char *data;
-
- returnData = dict_alloc();
-
- readData(&data);
-
- if(data) parseData(data, returnData);
-
- if(data) free(data);
-
- return returnData;
- }
-
-
-
-
-
-
-
-
-
-